%%%-------------------------------------------------------------------
%% @doc game public API
%% @end
%%%-------------------------------------------------------------------

-module(game_app).

-behaviour(application).

-include("common.hrl").
-include("lock_step_cb.hrl").
-export([start/0]).
-export([start/2, stop/1]).

start() ->
    try
        config:load_all_config(),
        ensure_apps(),
        start_app_services(),
        ok = application:start(?GAME_APP_NAME),
        ok
    catch
        Class:Reason:Stack ->
            start_fail(Class, Reason, Stack)
    end.

start_fail(Class, Reason, Stack) ->
    case get(game_log_prepared) of
        ?true ->
            ?LOG_ERROR("!!!!!!!!!!!!!!!!! START FAIL !!!!!!!!!!!!!!!!!!!~n"),
            ?LOG_ERROR("REASON: ~p~n~p~n~p~n~n", [Class, Reason, Stack]),
            init:stop(1);
        _ ->
            io:format("!!!!!!!!!!!!!!!!! START FAIL !!!!!!!!!!!!!!!!!!!~n"),
            io:format("REASON: ~p~n~p~n~p~n~n", [Class, Reason, Stack]),
            init:stop(1)
    end.


start(_StartType, _StartArgs) ->
    ?LOG_INFO("============================ GAME_SUP START ============================"),
    {ok, SupPid} = game_sup:start_link(),
    {ok, SupPid}.

stop(_State) ->
    ok.

%% internal functions

%% @doc 确保依赖的app开启
ensure_apps() ->
    ok = start_game_log(),
    ok = application:ensure_started(sasl),
    ok = inets:start(),
    ok = ssl:start(),
    ok = application:ensure_started(ranch),
    ok = network_app:start(),
    ok = start_game_db_app(),
    ok = start_elock_step_app(),
    ok.

start_game_log() ->
    application:set_env(game_log, game_config_mod, config),
    ok = game_log_app:start(?GAME_APP_NAME),
    put(game_log_prepared, true),
    game_util_log:set_log_mod(game_log),
    ok.

start_game_db_app() ->
    % 必选，设置配置模块
    application:set_env(db, game_config_mod, config),
    application:set_env(db, db_type_list, [?DB_TYPE_LOG, ?DB_TYPE_GAME]),
    ok = application:ensure_started(db),
    ok.

%% @doc 启动其他app的服务
start_app_services() ->
    web:start_http_service(),
    ok.

%% @doc 启动帧同步app
start_elock_step_app() ->
    % 必选，设置回调模块
    application:set_env(elock_step, callback_mod, lock_step_cb),
    ok = application:ensure_started(elock_step),
    % 启动完成sup后，启动匹配相关的进程池
    _ = [begin
             ChildSpec = lock_step_cb:match_svr_child_spec(MatchType),
             {ok, _} = game_util:start_child(elock_step_sup, ChildSpec)
         end||MatchType<- ?LS_MATCH_TYPE_LIST],
    ok.
